﻿using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Narwhunderful.Aphelia.Framework.UI;
using Narwhunderful.Aphelia.Framework.Input;
using Narwhunderful.Aphelia.Framework.Input.Keyboard;

namespace Narwhunderful.Aphelia.Framework.UI
{
    
    public class UIScreen : UIContainerComponent<UIComponent>
    {

        public EventHandler<TransitionStateChangedEventArgs> TransitionStateChanged;

        TransitionEffect _currentTransitionEffect;
        public TransitionEffect CurrentTransitionEffect
        {
            get
            {
                return _currentTransitionEffect;
            }
        }

        bool _autoRemove = true;
        public bool AutoRemove
        {
            get
            {
                return _autoRemove;
            }
            set
            {
                _autoRemove = value;
            }
        }

        UIComponent _focusedComponent = null;
        public UIComponent FocusedComponent
        {
            get
            {
                return _focusedComponent;
            }
            protected internal set
            {
                _focusedComponent = value;
            }
        }

        TransitionEffect _transitionEffectOn;
        public TransitionEffect TransitionEffectOn
        {
            get
            { 
                return _transitionEffectOn; 
            }
            protected set
            { 
                _transitionEffectOn = value;
            }
        }

        TransitionEffect _transitionEffectOff;
        public TransitionEffect TransitionEffectOff
        {
            get
            {
                return _transitionEffectOff;
            }
            protected set
            {
                _transitionEffectOff = value;
            }
        }

        TransitionState _transitionState = TransitionState.Idle;
        public TransitionState TransitionState
        {
            get
            {
                return _transitionState;
            }
        }

        public bool IsTransitioning
        {
            get
            {
                return (_transitionState == TransitionState.TransitioningOn || _transitionState == TransitionState.TransitioningOff);
            }
        }

        public UIScreen(HUD hud)
            : base(hud)
        {
            _currentTransitionEffect = new TransitionEffect(base.Game);
            base.Components.ParentScreen = this;
            base.Width = Game.GraphicsDevice.PresentationParameters.BackBufferWidth;
            base.Height = Game.GraphicsDevice.PresentationParameters.BackBufferHeight;
            base.ForegroundIsVisible = true;
        }

        #region IUpdatableComponent

        protected override void InternalUpdate(GameTime gameTime)
        {
            base.InternalUpdate(gameTime);
            if (IsTransitioning) UpdateTransition(gameTime);
        }

        public virtual void UpdateTransition(GameTime gameTime)
        {
            _currentTransitionEffect.Update(gameTime);
        }

        protected override void EndUpdate()
        {
            base.EndUpdate();
            if (_currentTransitionEffect.Progress == 1.0f)
            {
                TransitionState newState = TransitionState.Idle;
                if (_transitionState == TransitionState.TransitioningOn) newState = TransitionState.TransitionedOn;
                if (_transitionState == TransitionState.TransitioningOff) newState = TransitionState.TransitionedOff;
                OnTransitionStateChanged(this, new TransitionStateChangedEventArgs(newState, _transitionState));
            }
            else
            {
                base.NeedsUpdate = true;
            }
        }

        #endregion

        #region IDrawableComponent

        protected override void BeginSpriteBatch()
        {
            base.SpriteBatch.Begin(SpriteSortMode.Deferred, null, null, null, _currentTransitionEffect.RasterizerState, _currentTransitionEffect.BasicEffect);
        }

        protected override void InternalDrawForeground(GameTime gameTime)
        {
            base.InternalDrawForeground(gameTime);
            if (_focusedComponent != null) _focusedComponent.Draw(gameTime, true);
        }

        protected override void EndSpriteBatch()
        {
            if (base.IsFocused)
            {
                base.SpriteBatch.Tag = false;
                base.SpriteBatch.End();
            }
        }

        protected override void EndDraw()
        {
            EndSpriteBatch();
            base.EndDraw();
        }

        #endregion

        #region IKeyboardComponent

        protected internal override void OnKeyDown(object sender, KeyEventArgs e)
        {
            base.OnKeyDown(sender, e);
            if (_focusedComponent != null) _focusedComponent.OnKeyDown(sender, e);
        }

        protected internal override void OnKeyPress(object sender, KeyEventArgs e)
        {
            base.OnKeyPress(sender, e);
            if (_focusedComponent != null) _focusedComponent.OnKeyPress(sender, e);
        }

        protected internal override void OnKeyUp(object sender, KeyEventArgs e)
        {
            base.OnKeyUp(sender, e);
            if (_focusedComponent != null) _focusedComponent.OnKeyUp(sender, e);
        }

        #endregion

        #region IUIComponent

        internal override void ChangeFocusedComponent()
        {
            if (base.HUD.FocusedScreen != null) base.HUD.FocusedScreen.LoseFocus();
            base.HUD.FocusedScreen = this;
        }

        internal override void LoseFocusedComponent()
        {
            base.HUD.FocusedScreen = null;
        }

        #endregion

       public bool CanTransition()
       {
           if (_transitionEffectOn == null) return false;
           if (_transitionEffectOff == null) return false;
           return (!IsTransitioning);
       }

        public void TransitionOn()
        {
            if (CanTransition())
            {
                if (_transitionState == TransitionState.TransitionedOn) return;
                _currentTransitionEffect = _transitionEffectOn;
                OnTransitionStateChanged(this, new TransitionStateChangedEventArgs(TransitionState.TransitioningOn, _transitionState));
            }
        }

        public void TransitionOff()
        {
            if (CanTransition())
            {
                if (_transitionState == TransitionState.TransitionedOff) return;
                _currentTransitionEffect = _transitionEffectOff;
                OnTransitionStateChanged(this, new TransitionStateChangedEventArgs(TransitionState.TransitioningOff, _transitionState));
            }
        }

        protected internal void OnTransitionStateChanged(object sender, TransitionStateChangedEventArgs e)
        {
            if (e.State == e.OldState) return;
            base.NeedsUpdate = true;
            _transitionState = e.State;
            if (TransitionStateChanged != null) TransitionStateChanged(sender, e);
            if (e.State == TransitionState.TransitioningOn || e.State == TransitionState.TransitioningOff)
            {
                _currentTransitionEffect.CurrentScreen = this;
            }
            if (e.State == TransitionState.TransitionedOn) _currentTransitionEffect.Reset();
            if (e.State == TransitionState.TransitionedOff)
            {
                _currentTransitionEffect.Reset();
                if (_autoRemove) base.HUD.Components.Remove(this, true);
            }
        }

    }

}
